﻿using Coldairarrow.Entity;
using Coldairarrow.Entity.Backstage.UserData;
using Coldairarrow.Entity.Backstage.Valickets;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.BTB_StaffUsers;
using Coldairarrow.Entity.Frontstage.Valickets;
using Coldairarrow.Entity.Goods;
using Coldairarrow.Entity.Order;
using Coldairarrow.Entity.TurnPDF;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using Coldairarrow.Util.DbHelpers;
using Coldairarrow.Util.Helper;
using EFCore.Sharding;
using LinqKit;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using MyTest.OA.Common;
using Newtonsoft.Json;
using NUnit.Framework;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;
using static Coldairarrow.Business.IOrder_MasterBusiness;
using static Coldairarrow.Util.Helper.DataTableToExcel;

namespace Coldairarrow.Business
{//
    public class Order_MasterBusiness : BaseBusiness<Order_Master>, IOrder_MasterBusiness, ITransientDependency
    {
        private readonly IOperator _Operator;
        private readonly IHostingEnvironment _hostingEnvironment;

        public Order_MasterBusiness(IDbAccessor db, IOperator Operators, IHostingEnvironment hostingEnvironment)
            : base(db)
        {
            _Operator = Operators;
            _hostingEnvironment = hostingEnvironment;
        }

        #region 外部接口

        public async Task<PageResult<Order_Master>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<Order_Master>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<Order_Master, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<Order_Master> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(Order_Master data)
        {
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(Order_Master data)
        {
            await UpdateAsync(data);
        }

        public async Task DelDataAsync(List<string> ids)
        {
            await UpdateAsync(x=>ids.Contains(x.Id) && x.CreatorId.Equals(_Operator.UserId),z => z.OrderState = -1);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }

        #region --前台订单接口

        /// <summary>
        /// 生成订单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<OrderNum> AddOrderAsync(OrderDto dto)
        {
            /*1.从购物车生成订单
              2.订单为待支付状态（从购物车中移出）
              //3.订单超过30分钟未支付更改为订单取消
              4.订单支付成功之后更改支付状态为已支付
                订单状态为待发货，
                客户可以改变状态为已取消
                管理员修改状态为已发货,
             */

            var res = await Db.GetIQueryable<BTB_ShippingAddress>().SingleOrDefaultAsync(p => p.id.Equals(dto.AddressId));
            var rest = await Db.GetIQueryable<Invoice_Info>().SingleOrDefaultAsync(k => k.Id.Equals(dto.Invoice_Id));
            rest.Deleted = false;
            var resd = new { Address = res?.Address, DetailedAddress = res?.DetailedAddress };
            Order_Master _Master = new Order_Master
            {
                Id = IdHelper.GetId(),
                CreateTime = DateTime.Now,
                CreatorId = _Operator.UserId,
                Deleted = false,
                OrderCode = GetCode().OrderNm,
                TotalPrice = dto?._products.Sum(p => p.ProductPrice * p.Num),
                OrderState = 0,
                PayState = 0,
                Invoice_InfoId = dto?.Invoice_Id,
                Address_Id = dto?.AddressId,
                CreatorName = _Operator?.Property?.RealName,
                payeinfoName = res?.CreatorId,
                payeinfoAddress = resd.ToJson(),
                payeinfoPhone = res?.Phone
            };

            OrderNum order = new OrderNum();

            List<ProductDto> dtos = new List<ProductDto>();

            switch (dto.OrderFlag)
            {
                case 0:
                    dtos = await AddOrderAsync(dto, _Master);
                    break;

                case 1:
                    dtos = await AddCartOrderAsync(dto, _Master);
                    break;
            }
            if (dtos.Count() == 0)
            {
                int i = await InsertAsync(_Master);
                order.code = "200";
                order.msg = "生成订单成功";
                order.Order_Id = _Master.Id;
                return order;
            }
            order.code = "201";
            order.msg = "库存或其他错误";
            order.Order_Id = "";
            return order;
        }

        /// <summary>
        /// 获取订单信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<OrderProducts>> GetOrderData(PageInput<OrderProducts> input)
        {
            //DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            //long timeStamp = (long)(DateTime.Now - startTime).TotalSeconds; // 相差秒数
            if (input.Search.state.HasValue && input.Search.state < 4 && input.Search.state >= 0)
            {
                var t = input.Search;
                var res = Db.GetIQueryable<Order_Master>().Where(p => p.CreatorId.Equals(_Operator.UserId) && p.OrderState != 5);
                if (!t.state.IsNullOrEmpty())
                {
                    res = res.Where(p => p.OrderState.Equals(t.state));
                }
                if (!t.OrderCode.IsNullOrEmpty())
                {
                    res = res.Where(p => p.OrderCode.Equals(t.OrderCode));
                }

                int count = res.Count();
                try
                {
                    var result = await res.OrderBy(p => p.CreateTime).Select(p =>
                    new OrderProducts
                    {
                        Id = p.Id,
                        CreatTime = p.CreateTime,
                        OrderCode = p.OrderCode,
                        state = p.OrderState,
                        unixTime = p.unixTime,
                        IsPointOrder = p.IsPointOrder,
                        TatolPrice = p.TotalPrice,
                        payState = p.PayState,
                        TotalPoint = p.TotalPoint,
                        IsDiscuss = p.IsDiscuss,
                        YSMoney =p.YSMoney,
                        InvoiceData =p.InvoiceData,
                        InvoiceState = p.InvoiceState,
                        payeinfoAddress = p.payeinfoAddress,
                        payeinfoPhone = p.payeinfoPhone,
                        payeinfoName=p.payeinfoName,
                        //Invoice = Db.GetIQueryable<Invoice_Info>(true).SingleOrDefault(r => r.Id.Equals(p.Invoice_InfoId)),
                        //AddressDto = Db.GetIQueryable<BTB_ShippingAddress>(true).SingleOrDefault(r => r.id.Equals(p.Address_Id)),
                        TicketDTO = Db.GetIQueryable<BS_UserVailTicket>(true).SingleOrDefault(r => r.Id.Equals(p.VailTicketId)),
                        orderProducts = Db.GetIQueryable<Order_Decimal>(true).Where(s => s.OrderCode.Equals(p.OrderCode) && s.OrderMaster_Id.Equals(p.Id))
                                  .Select(s => new OrderProduct
                                  {
                                      Id = s.Id,
                                      productId = s.Product_Id,
                                      Price = s.ProductPrice,
                                      Image = s.ProductImage,
                                      itemName = s.ProductitemNames,
                                      Name = s.ProductNames,
                                      Num = (int)s.Products_Num,
                                      DATA0 = (s.DATA0 == null || s.DATA0 == "") ? "0" : s.DATA0
                                  })
                    }).OrderByDescending(x => x.CreatTime).Skip((input.PageIndex - 1) * input.PageRows)
                       .Take(input.PageRows)
                       .ToListAsync();
                        return new PageResult<OrderProducts> { Data = result, Total = count };
                    }
                    catch (Exception E)
                    {

                        throw;
                    }
            }
            else if (input.Search.state.HasValue && input.Search.state == 4)
            {
                int[] stList =  { 3, 4, 6};
                var t = input.Search;
                var res = Db.GetIQueryable<Order_Master>().Where(p => p.CreatorId.Equals(_Operator.UserId) && p.OrderState != 5);
                if (!t.state.IsNullOrEmpty())
                {
                    res = res.Where(p => stList.Contains((int)p.OrderState));
                }
                if (!t.OrderCode.IsNullOrEmpty())
                {
                    res = res.Where(p => p.OrderCode.Equals(t.OrderCode));
                }

                int count = res.Count();
                try
                {
                    var result = await res.OrderBy(p => p.CreateTime).Select(p =>
                    new OrderProducts
                    {
                        Id = p.Id,
                        CreatTime = p.CreateTime,
                        OrderCode = p.OrderCode,
                        state = p.OrderState,
                        unixTime = p.unixTime,
                        IsPointOrder = p.IsPointOrder,
                        TatolPrice = p.TotalPrice,
                        payState = p.PayState,
                        TotalPoint = p.TotalPoint,
                        IsDiscuss = p.IsDiscuss,
                        YSMoney = p.YSMoney,
                        InvoiceData = p.InvoiceData,
                        InvoiceState = p.InvoiceState,
                        payeinfoAddress = p.payeinfoAddress,
                        payeinfoPhone = p.payeinfoPhone,
                        payeinfoName = p.payeinfoName,
                        //AddressDto = Db.GetIQueryable<BTB_ShippingAddress>(true).SingleOrDefault(r => r.id.Equals(p.Address_Id)),
                        TicketDTO = Db.GetIQueryable<BS_UserVailTicket>(true).SingleOrDefault(r => r.Id.Equals(p.VailTicketId)),
                        orderProducts = Db.GetIQueryable<Order_Decimal>(true).Where(s => s.OrderCode.Equals(p.OrderCode) && s.OrderMaster_Id.Equals(p.Id))
                                  .Select(s => new OrderProduct
                                  {
                                      Id = s.Id,
                                      productId = s.Product_Id,
                                      productItemId = s.Products_Id,
                                      Price = s.ProductPrice,
                                      Image = s.ProductImage,
                                      itemName = s.ProductitemNames,
                                      Name = s.ProductNames,
                                      Num = (int)s.Products_Num,
                                      DATA0 = (s.DATA0 == null || s.DATA0 == "")  ? "0": s.DATA0
                                  })
                    }).OrderByDescending(x => x.CreatTime).Skip((input.PageIndex - 1) * input.PageRows)
                       .Take(input.PageRows)
                       .ToListAsync();
                        return new PageResult<OrderProducts> { Data = result, Total = count };
                }
                catch (Exception E)
                {

                    throw;
                }
            }
            else if (input.Search.state.HasValue && input.Search.state == 5)
            {
                var t = input.Search;
                var res = Db.GetIQueryable<Order_Master>().Where(p => p.CreatorId.Equals(_Operator.UserId) && p.OrderState > 6);
               
                if (!t.OrderCode.IsNullOrEmpty())
                {
                    res = res.Where(p => p.OrderCode.Equals(t.OrderCode));
                }

                int count = res.Count();
                try
                {
                    var result = await res.OrderBy(p => p.CreateTime).Select(p =>
                    new OrderProducts
                    {
                        Id = p.Id,
                        CreatTime = p.CreateTime,
                        OrderCode = p.OrderCode,
                        state = p.OrderState,
                        unixTime = p.unixTime,
                        IsPointOrder = p.IsPointOrder,
                        TatolPrice = p.TotalPrice,
                        payState = p.PayState,
                        TotalPoint = p.TotalPoint,
                        InvoiceData = p.InvoiceData,
                        InvoiceState = p.InvoiceState,
                        payeinfoAddress = p.payeinfoAddress,
                        payeinfoPhone = p.payeinfoPhone,
                        payeinfoName = p.payeinfoName,
                        //AddressDto = Db.GetIQueryable<BTB_ShippingAddress>(true).SingleOrDefault(r => r.id.Equals(p.Address_Id)),
                        TicketDTO = Db.GetIQueryable<BS_UserVailTicket>(true).SingleOrDefault(r => r.Id.Equals(p.VailTicketId)),
                        orderProducts = Db.GetIQueryable<Order_Decimal>(true).Where(s => s.OrderCode.Equals(p.OrderCode) && s.OrderMaster_Id.Equals(p.Id))
                                  .Select(s => new OrderProduct
                                  {
                                      Id = s.Id,
                                      productId = s.Product_Id,
                                      Price = s.ProductPrice,
                                      Image = s.ProductImage,
                                      itemName = s.ProductitemNames,
                                      Name = s.ProductNames,
                                      Num = (int)s.Products_Num,
                                      DATA0 = (s.DATA0 == null || s.DATA0 == "") ? "0" : s.DATA0
                                  })
                    }).OrderByDescending(x => x.CreatTime).Skip((input.PageIndex - 1) * input.PageRows)
                       .Take(input.PageRows)
                       .ToListAsync();
                        return new PageResult<OrderProducts> { Data = result, Total = count };
                    }
                    catch (Exception E)
                    {

                        throw;
                    }

            }
            else
            {
                var t = input.Search;
                var res = Db.GetIQueryable<Order_Master>().Where(p => p.CreatorId.Equals(_Operator.UserId));
                if (!t.state.IsNullOrEmpty())
                {
                    res = res.Where(p => p.OrderState.Equals(t.state));
                }
                if (!t.OrderCode.IsNullOrEmpty())
                {
                    res = res.Where(p => p.OrderCode.Equals(t.OrderCode));
                }

                int count = res.Count();
                try
                {
                    var result = await res.OrderBy(p => p.CreateTime).Select(p =>
                new OrderProducts
                {
                    Id = p.Id,
                    CreatTime = p.CreateTime,
                    OrderCode = p.OrderCode,
                    state = p.OrderState,
                    unixTime = p.unixTime,
                    IsPointOrder = p.IsPointOrder,
                    TatolPrice = p.TotalPrice,
                    payState = p.PayState,
                    TotalPoint = p.TotalPoint,
                    InvoiceData = p.InvoiceData,
                    InvoiceState = p.InvoiceState,
                    payeinfoAddress = p.payeinfoAddress,
                    payeinfoPhone = p.payeinfoPhone,
                    payeinfoName = p.payeinfoName,
                    //AddressDto = Db.GetIQueryable<BTB_ShippingAddress>(true).SingleOrDefault(r => r.id.Equals(p.Address_Id)),
                    TicketDTO = Db.GetIQueryable<BS_UserVailTicket>(true).SingleOrDefault(r => r.Id.Equals(p.VailTicketId)),
                    orderProducts = Db.GetIQueryable<Order_Decimal>(true).Where(s => s.OrderCode.Equals(p.OrderCode) && s.OrderMaster_Id.Equals(p.Id))
                              .Select(s => new OrderProduct
                              {
                                  Id = s.Id,
                                  productId = s.Product_Id,
                                  Price = s.ProductPrice,
                                  Image = s.ProductImage,
                                  itemName = s.ProductitemNames,
                                  Name = s.ProductNames,
                                  Num = (int)s.Products_Num,
                                  DATA0 = (s.DATA0 == null || s.DATA0 == "") ? "0" : s.DATA0
                              })
                }).OrderByDescending(x => x.CreatTime).Skip((input.PageIndex - 1) * input.PageRows)
                   .Take(input.PageRows)
                   .ToListAsync();
                    return new PageResult<OrderProducts> { Data = result, Total = count };
                }
                catch (Exception E)
                {

                    throw;
                }

            }  
        }

        public async Task<OrderProducts> GetTheOrderData(OrderProducts input)
        {
            var res = Db.GetIQueryable<Order_Master>().Where(p => p.Id.Equals(input.Id));

            int count = res.Count();
            var result = await (from p in res
                         join b in Db.GetIQueryable<BTB_RefundMaster>() on p.Id equals b.OrderId into ab
                         from b in ab.DefaultIfEmpty()
                         select new OrderProducts
                         {
                             Id = p.Id,
                             CreatTime = p.CreateTime,
                             OrderCode = p.OrderCode,
                             state = p.OrderState,
                             TatolPrice = p.TotalPrice,
                             AddressId = p.Address_Id,
                             payState = p.PayState,
                             IsDiscuss = p.IsDiscuss,
                             YSMoney = p.YSMoney,
                             IsPointOrder = p.IsPointOrder,
                             TotalPoint = p.TotalPoint,
                             LscCompany = p.LscCompany,
                             LscNumber = p.LscNumber,
                             Note = p.DATA2,
                             InvoiceData = p.InvoiceData,
                             InvoiceState = p.InvoiceState,
                             payeinfoAddress = p.payeinfoAddress,
                             payeinfoPhone = p.payeinfoPhone,
                             payeinfoName = p.payeinfoName,
                             NotRefundReasion = b.NoPassResion,
                             TicketDTO = Db.GetIQueryable<BS_UserVailTicket>(true).SingleOrDefault(r => r.Id.Equals(p.VailTicketId)),
                             orderProducts = Db.GetIQueryable<Order_Decimal>(false).Where(s => s.OrderCode.Equals(p.OrderCode) && s.OrderMaster_Id.Equals(p.Id))
                           .Select(s => new OrderProduct
                           {
                               Id = s.Id,
                               Price = s.ProductPrice,
                               productId = s.Product_Id,
                               Image = s.ProductImage,
                               itemName = s.ProductitemNames,
                               Name = s.ProductNames,
                               DATA0 = s.DATA0,
                               Num = (int)s.Products_Num

                           })
                         }).ToListAsync();

            return result.FirstOrDefault();
        }

        /// <summary>
        /// 取消订单
        /// </summary>
        /// <param name="canncl"></param>
        /// <returns></returns>
        public async Task CancelOrderAsync(CannclOrder canncl)
        {
            try
            {
                if (canncl.Id != null)
                {
                    string key = RedisHelper.Get("Order:" + canncl.Id);
                    if (key != null)
                    {
                        RedisHelper.Del("Order:" + canncl.Id);
                    }
                }

                var res = await Db.GetIQueryable<Order_Master>().SingleOrDefaultAsync(p => p.Id.Equals(canncl.Id));

                var rest = await Db.GetIQueryable<Outbound_Details>().FirstOrDefaultAsync(r => r.OrderMater_Id.Equals(res.Id));
                var Products_Id = rest?.Products_Id;
                var Product_Id = rest?.Product_Id;

                var result = await Db.GetIQueryable<BTB_GoodsSpecificationsItem>()
                    .FirstOrDefaultAsync(s => s.GoodsSpecificationsItemID.Equals(Products_Id) && s.GoodsID.Equals(Product_Id));
                if (res != null)
                {
                    if (res.OrderState == 0)
                    {

                        //返回代金券
                        if (!res.VailTicketId.IsNullOrEmpty())
                        {
                            var utList = Db.GetIQueryable<BS_UserVailTicket>().Where(x => x.Id.Equals(res.VailTicketId)).ToList();
                            if (utList.Count > 0)
                            {
                                utList[0].UseState = 0;
                                await Db.UpdateAsync(utList[0]);
                            }
                        }


                        res.OrderState = 5;
                        res.PayState = 0;
                        await Db.UpdateAsync(res);

                        if (rest != null)
                        {
                            await Db.DeleteAsync<Outbound_Details>(rest);
                            //rest.Bound_Flag = 3;
                            //await Db.UpdateAsync(rest);
                        }
                        if (result != null)
                        {
                            result.Inventory = result.Inventory +decimal.ToInt32((decimal)rest.Outbound_Num);
                            await Db.UpdateAsync(result);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw;
            }
        }

        #endregion --前台订单接口

        #region ---后台接口

        /// <summary>
        /// 获取订单信息 --后台
        /// </summary>
        /// <param name="order_"></param>
        /// <returns></returns>
        public async Task<PageResult<Order_Dto>> GetOrderDataTwo(PageInput<Order_DtoTwo> order_)
        {
            var seach = order_.Search;

            var whereone = LinqHelper.True<Order_Master>();
            var wherenew= LinqHelper.True<Order_Dto>();
            var wheretwo = LinqHelper.True<BTB_StaffUser>();
            if (!string.IsNullOrWhiteSpace(seach.OrderCore))
            {
                Expression<Func<Order_Dto, bool>> expression = r => (r.NumCode.Contains(seach.OrderCore) || r.NameUser.Contains(seach.OrderCore));
                wherenew = wherenew.And(expression);
            }

            if (seach.state != null)
            {
                Expression<Func<Order_Master, bool>> expression = r => r.OrderState.Equals(seach.state);
                whereone = whereone.And(expression);
            }

            if (!string.IsNullOrWhiteSpace(seach.Shop_Name))
            {
                Expression<Func<BTB_StaffUser, bool>> expressiontwo = t => t.Name.Equals(seach.Shop_Name);
                wheretwo = wheretwo.And(expressiontwo);
            }

            if (!string.IsNullOrWhiteSpace(seach.Shop_Phone))
            {
                Expression<Func<BTB_StaffUser, bool>> expressiontwo = t => t.phone.Contains(seach.Shop_Phone);
                wheretwo = wheretwo.And(expressiontwo);
            }

            if (!seach.startTime.IsNullOrEmpty())
            {
                Expression<Func<Order_Master, bool>> expression = t => t.CreateTime >= seach.startTime && t.CreateTime <= seach.endTime;
                whereone = whereone.And(expression);
            }

            var res = from p in Db.GetIQueryable<Order_Master>().Where(whereone)
                      join k in Db.GetIQueryable<BTB_StaffUser>().Where(wheretwo) on p.CreatorId equals k.id
                      select new Order_Dto
                      {
                          Id = p.Id,
                          NameUser = k.NickName,
                          PhoneUser = k.phone,
                          AllPrice = p.TotalPrice,
                          OrderState = p.OrderState,
                          CreatTime = p.CreateTime,
                          payeinfoName = p.payeinfoName,
                          InvoiceState = p.InvoiceState,
                          PayState = p.PayState,
                          payeinfoPhone = p.payeinfoPhone,
                          payeinfoAddress = p.payeinfoAddress,
                          NumCode = p.OrderCode,
                          InvoiceId = p.Invoice_InfoId,
                          Invoice = Db.GetIQueryable<Invoice_Info>(false).SingleOrDefault(r => r.Id.Equals(p.Invoice_InfoId)),
                          _Decimal = Db.GetIQueryable<Order_Decimal>(false).Where(s => s.OrderMaster_Id.Equals(p.Id))
                      };

            var Total = res.Where(wherenew).ToList().Count;
            var ps = await res.Where(wherenew).OrderByDescending(p => p.CreatTime).Skip((order_.PageIndex - 1) * order_.PageRows)
                           .Take(order_.PageRows)
                           .ToListAsync();
            return new PageResult<Order_Dto> { Data = ps, Total = Total }; ;
        }

        /// <summary>
        /// 生成订单（事务）
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<OrderNum> AddOrderTwoAsync(OrderDto dto)
        {
            var res = await Db.GetIQueryable<BTB_ShippingAddress>().SingleOrDefaultAsync(p => p.id.Equals(dto.AddressId));
            var rest = await Db.GetIQueryable<Invoice_Info>().SingleOrDefaultAsync(k => k.Id.Equals(dto.Invoice_Id));
            rest.Deleted = false;
            var resd = new { Address = res?.Address, DetailedAddress = res?.DetailedAddress };
            var unix = DateTime.Now;
           
            Order_Master _Master = new Order_Master
            {
                Id = IdHelper.GetId(),
                CreateTime = unix,
                CreatorId = _Operator.UserId,
                Deleted = false,
                OrderCode = GetCode().OrderNm,
                TotalPrice = dto?._products.Sum(p => p.ProductPrice * p.Num),
                OrderState = 0,
                Totalnum = dto?._products.Sum(p => p.Num),
                PayState = 0,
                Invoice_InfoId = dto?.Invoice_Id,
                Address_Id = dto?.AddressId,
                CreatorName = _Operator?.Property?.RealName,
                payeinfoName = res?.CreatorId,
                payeinfoAddress = resd?.ToJson(),
                payeinfoPhone = res?.Phone,
                unixTime = unix.ToUnixTimeStamp()
            };
            List<ProductDto> dtos = new List<ProductDto>();
            OrderNum order = new OrderNum();
            var SUCCESS = await Db.RunTransactionAsync(async () =>
              {
                  switch (dto.OrderFlag)
                  {
                      case 0:
                          dtos = await AddOrderAsync(dto, _Master);
                          break;

                      case 1:
                          dtos = await AddCartOrderAsync(dto, _Master);
                          break;
                  }
                  if (dtos.Count() == 0)
                  {
                    
                      int i = await InsertAsync(_Master);
                      await Db.UpdateAsync(rest);
                  }
              });

            if (SUCCESS.Success == true)
            {
                
                // Assert.AreEqual(SUCCESS.Success, true);
                order.code = "200";
                order.msg = "生成订单成功";
                order.Data = DateTime.Now;
                order.DataSpan =(long) _Master.unixTime;
                order.Order_Id = _Master.Id;
                if (order.Order_Id != null)
                {
                    try
                    {
                        string values = order.Order_Id + order.DataSpan;
                        RedisHelper.Set("Order:" + order.Order_Id, values, 1800);
                    }
                    catch (Exception e)
                    {
                        LogHelper.WriteLog_LocalTxt(e.ToString());
                        throw e;
                    }
                }
                return order;
            }
            else
            {
                LogHelper.WriteLog_LocalTxt(SUCCESS.ex.ToString());
            }

            order.code = "201";
            order.msg = "库存或其他错误";
            order.Order_Id = "";
            return order;
        }

        /// <summary>
        /// 修改发货地址
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task ChangeAddressInfo(ChangeAddressInfoDTO input)
        {
            var model = await GetIQueryable().Where(x => x.Id.Equals(input.Id)).ToListAsync();
            if (model.Count == 0)
            {
                throw new BusException("订单信息查询失败，请重试", -308);
            }
            else
            {
                Base_UserLog data = new Base_UserLog();
                data.Id = IdHelper.GetId();
                data.CreateTime = DateTime.Now;
                data.CreatorId = _Operator.UserId;
                data.CreatorRealName = _Operator.Property.RealName;
                data.LogType = "修改购货地址";

                data.LogContent = "修改订单"+ model[0].Id + "购货地址";
                if (!input.payeinfoName.IsNullOrEmpty())
                {
                    data.LogContent += "收货人" + model[0].payeinfoName + "为" + input.payeinfoName;
                    model[0].payeinfoName = input.payeinfoName;
                   
                }
                if (!input.payeinfoAddress.IsNullOrEmpty())
                {
                    data.LogContent += "收货地址" + model[0].payeinfoAddress + "为" + input.payeinfoAddress;
                    model[0].payeinfoAddress = input.payeinfoAddress;
                }
                if (!input.payeinfoPhone.IsNullOrEmpty())
                {
                    data.LogContent += "收货电话" + model[0].payeinfoPhone + "为" + input.payeinfoPhone;
                    model[0].payeinfoPhone = input.payeinfoPhone;
                }

                await UpdateAsync(model[0]);
                await Db.InsertAsync(data);
            }
        
        }

        /// <summary>
        /// 修改发票状态信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task ChangeOrderInvoiceStateAsnyc(IdInputDTO input)
        {
            var model = await GetIQueryable().Where(x => x.Id.Equals(input.id)).ToListAsync();
            if (model[0].InvoiceState == 1) 
            {
                model[0].InvoiceState = 2;
                await UpdateAsync(model[0]);
            }
            else
            {
                throw new BusException("此订单无发票或者已开发票，无法重复提交！");
            }
        }

        /// <summary>
        /// 生成订单_JWF
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<OrderNum> SetToOrderAsync(SetOrderDto dto)
        {
            Log.Information("进入生成订单===========》");
            var res = await Db.GetIQueryable<BTB_ShippingAddress>().SingleOrDefaultAsync(p => p.id.Equals(dto.AddressId));
            var rest = await Db.GetIQueryable<Invoice_Info>().SingleOrDefaultAsync(k => k.Id.Equals(dto.Invoice_Id));
            
            if (!rest.IsNullOrEmpty())
            {
                rest.Deleted = false;
            }
            
            var resd = new { Address = res?.Address, DetailedAddress = res?.DetailedAddress };
            Log.Information("订单地址信息resd = {0}",resd.ToJson().ToString());
            var unix = DateTime.Now;

            decimal totalPrice = 0;
            decimal djMoney = 0;
            int totalNum = 0;

            Order_Master _Master = new Order_Master
            {
                Id = IdHelper.GetId(),
                CreateTime = unix,
                CreatorId = _Operator.UserId,
                Deleted = false,
                OrderCode = GetCode().OrderNm,
                OrderState = 0,
                VailTicketId = dto.VailTicketId,
                Totalnum = totalNum,
                PayState = 0,
                TotalPrice = totalPrice,
                Invoice_InfoId = dto?.Invoice_Id,
                Address_Id = dto?.AddressId,
                InvoiceData = rest?.ToJson().ToString(), 
                InvoiceState = (rest == null)?0:1,
                CreatorName = _Operator?.Property?.RealName,
                payeinfoName = res?.CreatorId,
                payeinfoAddress = resd?.ToJson(),
                payeinfoPhone = res?.Phone,
                DATA2 = dto.Note,
                unixTime = unix.ToUnixTimeStamp()
            };

            Log.Information("订单Id orderId = {0}", _Master.Id);

            #region//判断是否使用代金券
            BS_UserVailTicket uvModel = new BS_UserVailTicket();
            if (!_Master.VailTicketId.IsNullOrEmpty())
            {
                var theTime = DateTime.Now;
                var dList = Db.GetIQueryable<BS_UserVailTicket>().Where(x => x.Id.Equals(_Master.VailTicketId) && x.UserId.Equals(_Operator.UserId) && x.UseState == 0 && x.EndTime >= theTime).ToList();

                if (dList.Count > 0)
                {
                    Log.Information("订单优惠金额 Ticket_Amount = {0}", dList[0].Ticket_Amount);
                    djMoney = dList[0].Ticket_Amount;
                    dList[0].UseState = 1;
                    uvModel = dList[0];

                }
                else
                {
                    throw new BusException("查询代金券信息失败，生成订单失败！", -3);
                }
            }
            #endregion

            List<ProductDto> dtos = new List<ProductDto>();
            OrderNum order = new OrderNum();
            Log.Information("订单生成方式 OrderFlag = {0}", dto.OrderFlag);
            var SUCCESS = await Db.RunTransactionAsync(async () =>
            {
                switch (dto.OrderFlag)
                {
                    case 0:
                        dtos = await STOrderAsync(dto, _Master);
                        break;

                    case 1:
                        dtos = await STCartOrderAsync(dto, _Master);
                        break;
                }

              
                if (dtos.Count() == 0)
                {
                    _Master.YSMoney = (decimal)_Master.TotalPrice;
                    if (djMoney > 0)
                    {
                        await Db.UpdateAsync(uvModel);
                        _Master.TotalPrice -= djMoney;
                    }

                    int i = await InsertAsync(_Master);
                    if (!rest.IsNullOrEmpty())
                    {
                        await Db.UpdateAsync(rest);
                    }
                   
                }
            });

            if (SUCCESS.Success == true)
            {

                // Assert.AreEqual(SUCCESS.Success, true);
                order.code = "200";
                order.msg = "生成订单成功";
                order.price = _Master.TotalPrice;
                order.Data = DateTime.Now;
                order.DataSpan = (long)_Master.unixTime;
                order.Order_Id = _Master.Id;
                if (order.Order_Id != null)
                {
                    try
                    {
                        string values = order.Order_Id + order.DataSpan;
                        RedisHelper.Set("Order:" + order.Order_Id, values, 1800);
                    }
                    catch (Exception e)
                    {
                        LogHelper.WriteLog_LocalTxt(e.ToString());
                        throw e;
                    }
                }
                Log.Information("生成订单成功《=========== ");
                return order;
            }
            else
            {
                LogHelper.WriteLog_LocalTxt(SUCCESS.ex.ToString());
            }

            order.code = "201";
            order.msg = "库存或其他错误";
            order.Order_Id = "";
            return order;
        }


        /// <summary>
        /// 生成订单（事务）
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<OrderNum> PointGoodOrderAsync(PointOrderDto dto)
        {
            OrderNum order = new OrderNum();
            dto.OrderFlag = 0;

            if (dto.IsNullOrEmpty() || dto._products.Count == 0)
            {
                order.code = "205";
                order.msg = "请选择你需要购买的商品后重试！";
                order.Order_Id = "";
                return order;
            }

            foreach (var item in dto._products)
            {
                var giModel = Db.GetIQueryable<BTB_GoodsSpecificationsItem>().Where(x => x.GoodsID.Equals(item.GoodId) && x.GoodsSpecificationsItemID.Equals(item.GoodItemId)).FirstOrDefault();
                var gModel = Db.GetIQueryable<BTB_Goods>().Where(x => x.ID.Equals(item.GoodId)).FirstOrDefault();
                if (giModel.IsNullOrEmpty() || gModel.IsNullOrEmpty())
                {
                    order.code = "206";
                    order.msg = "查询商品详情失败，请重新选择购买！";
                    order.Order_Id = "";
                    return order;
                }

                item.ProductNames = gModel.GoodsName;
                item.ProductitemNames = giModel.GoodsSpecifications;
                item.ProductImage = giModel.Pic;
                item.PointPrice = giModel.PointPrice;
            }


            var spt = dto?._products.Sum(p => p.PointPrice * p.Num);
            int sumPoint = spt.HasValue?(int)spt:0;
            if (sumPoint == 0)
            {
                order.code = "203";
                order.msg = "请选择你需要购买的商品后重试！";
                order.Order_Id = "";
                return order;
            }

            //获取用户积分
            int pCount = 0;
            var sModel = Db.GetIQueryable<BS_UserICPoint>().Where(x => x.UserId.Equals(_Operator.UserId)).OrderByDescending(x => x.Id).FirstOrDefault();
            if (!sModel.IsNullOrEmpty())
            {
                pCount = sModel.Point;
            }

            if(pCount < sumPoint)
            {
                order.code = "204";
                order.msg = "积分数量不足，购买失败！";
                order.Order_Id = "";
                return order;
            }

            sModel.Point -= sumPoint;


            var res = await Db.GetIQueryable<BTB_ShippingAddress>().SingleOrDefaultAsync(p => p.id.Equals(dto.AddressId));
            var resd = new { Address = res?.Address, DetailedAddress = res?.DetailedAddress };
            var unix = DateTime.Now;

            //生成订单
            Order_Master _Master = new Order_Master
            {
                Id = IdHelper.GetId(),
                CreateTime = unix,
                CreatorId = _Operator.UserId,
                Deleted = false,
                OrderCode = IdHelper.GetId(),
                TotalPoint = dto?._products.Sum(p => p.PointPrice * p.Num),
                IsPointOrder = true,
                OrderState = 0,
                Totalnum = dto?._products.Sum(p => p.Num),
                PayState = 1,
                Address_Id = dto?.AddressId,
                CreatorName = _Operator?.Property?.RealName,
                payeinfoName = res?.CreatorId,
                payeinfoAddress = resd?.ToJson(),
                payeinfoPhone = res?.Phone,
                unixTime = unix.ToUnixTimeStamp()
            };

            List<ProductDto> dtos = new List<ProductDto>();
           
            var SUCCESS = await Db.RunTransactionAsync(async () =>
            {
                switch (dto.OrderFlag)
                {
                    case 0:
                        dtos = await AddOrderAsync(dto, _Master);
                        break;
                }
                if (dtos.Count() == 0)
                {

                    int i = await InsertAsync(_Master);
                }
            });

            if (SUCCESS.Success == true)
            {
                Db.Update(sModel);
                order.code = "200";
                order.msg = "生成订单成功";
                order.Data = DateTime.Now;
                order.DataSpan = (long)_Master.unixTime;
                order.Order_Id = _Master.Id;
                if (order.Order_Id != null)
                {
                    try
                    {
                        string values = order.Order_Id + order.DataSpan;
                        RedisHelper.Set("Order:" + order.Order_Id, values, 1800);
                    }
                    catch (Exception e)
                    {
                        LogHelper.WriteLog_LocalTxt(e.ToString());
                        throw e;
                    }
                }
                return order;
            }
            else
            {
                LogHelper.WriteLog_LocalTxt(SUCCESS.ex.ToString());
            }

            order.code = "201";
            order.msg = "库存或其他错误";
            order.Order_Id = "";
            return order;
        }

        #endregion ---后台接口

        #endregion 外部接口

        #region 私有成员

        /// <summary>
        /// 积分购买商品—JWF
        /// </summary>
        /// <param name="_dto"></param>
        /// <param name="order_"></param>
        /// <returns></returns>
        private async Task<List<ProductDto>> AddOrderAsync(PointOrderDto _dto, Order_Master order_)
        {
            List<ProductDto> _product = new List<ProductDto>();
            List<Order_Decimal> _Decimals = new List<Order_Decimal>();
            List<Outbound_Details> outbound_s = new List<Outbound_Details>();
            //存储购物车中有的数据 res
            List<Shop_Cart> list = new List<Shop_Cart>();

            foreach (var item in _dto._products)
            {
                var gModel = Db.GetEntity<BTB_Goods>(item.GoodId);
                if (gModel.IsPointGoods == false)
                {
                    throw new BusException("非积分商品无法使用积分兑换!");
                }

                string str = $"EXEC WashNum '{item.GoodId}','{item.GoodItemId}'";
                var q = DbHelperSQL.QueryForObject<NumCode>(str);
                //分开之后删除
                if (q.Num > item.Num)
                {
                    #region 订单详情
                    Order_Decimal _Decimal = new Order_Decimal
                    {
                        Id = IdHelper.GetId(),
                        Deleted = false,
                        CreateTime = order_.CreateTime,
                        CreatorId = order_.CreatorId,
                        OrderMaster_Id = order_.Id,
                        OrderCode = order_.OrderCode,
                        Product_Id = item.GoodId,
                        Products_Id = item.GoodItemId,
                        Products_Num = item.Num,
                        ProductImage = item.ProductImage,
                        ProductNames = item.ProductNames,
                        ProductitemNames = item.ProductitemNames,
                        PointPrice = item.PointPrice,
                        SumPoint = (item.Num * item.PointPrice),
                        DATA0 = "0"
                    };
                    _Decimals.Add(_Decimal);

                    #endregion

                    #region 库存信息
                    Outbound_Details _Details = new Outbound_Details
                    {
                        Id = IdHelper.GetId(),
                        Deleted = false,
                        CreateTime = order_.CreateTime,
                        CreatorId = order_.CreatorId,
                        Product_Id = item.GoodId,
                        Products_Id = item.GoodItemId,
                        productName = item.ProductNames,
                        productsName = item.ProductitemNames,
                        Outbound_Num = item.Num,
                        OrderMater_Id = order_.Id,
                        OrderCode = order_.OrderCode,
                        PointPrice = item.PointPrice,
                        oldBalance = q.Num,
                        newBalance = (q.Num - item.Num),
                        Bound_Flag = 2,
                        DATA0 = q.Flag.ToString(),
                        TotalPoint = (item.Num * item.PointPrice)

                    };           
                    outbound_s.Add(_Details);
                    #endregion
                }
                else
                {
                    ProductDto product = new ProductDto
                    {
                        Id = item.GoodId,
                        itemId = item.GoodItemId
                    };
                    _product.Add(product);
                    if (product != null)
                    {
                        return _product;
                    }
                    throw new Exception("库存不足");
                }
            }

            if (_Decimals.Count() != 0)
            {
                try
                {
                    int t = await Db.InsertAsync(_Decimals, false);

                    int bound = await Db.InsertAsync(outbound_s, false);//添加减少库存信息

                }
                catch (Exception e)
                {
                    throw new Exception("订单生成失败");
                }
            }

            return _product;
        }


        /// <summary>
        /// 直接购买商品——JWF
        /// </summary>
        /// <param name="_dto"></param>
        /// <param name="order_"></param>
        /// <returns></returns>
        private async Task<List<ProductDto>> AddOrderAsync(OrderDto _dto, Order_Master order_)
        {
            List<ProductDto> _product = new List<ProductDto>();
            List<Order_Decimal> _Decimals = new List<Order_Decimal>();
            List<Outbound_Details> outbound_s = new List<Outbound_Details>();
            //存储购物车中有的数据 res
            List<Shop_Cart> list = new List<Shop_Cart>();

            foreach (var item in _dto._products)
            {
                string str = $"EXEC WashNum '{item.GoodId}','{item.GoodItemId}'";
                var q = DbHelperSQL.QueryForObject<NumCode>(str);
                //分开之后删除
                var res = Db.GetIQueryable<Shop_Cart>().FirstOrDefault(p => p.CreatorId.Equals(_Operator.UserId) && p.Products_Id.Equals(item.GoodItemId));
                if (q.Num > item.Num)
                {
                    Log.Information("订单加入商品规格Id = {0}", item.GoodItemId);
                    if (!item.GoodItemId.IsNullOrEmpty())
                    {
                        string goodsPic = "";
                        if (item.ProductImage.IsNullOrEmpty())
                        {
                            var gsModel = Db.GetIQueryable<BTB_GoodsSpecificationsItem>().Where(x => x.GoodsSpecificationsItemID == item.GoodItemId).ToList();
                            if (gsModel.Count > 0)
                            {
                                if (gsModel[0].Pic.IsNullOrEmpty())
                                {
                                    Log.Information("订单加入商品规格的商品Id = {0}", gsModel[0].GoodsID);
                                    var gModel = Db.GetIQueryable<BTB_Goods>().Where(x => x.ID == gsModel[0].GoodsID).ToList();
                                    if (gModel.Count > 0)
                                    {
                                        goodsPic = gModel[0].GoodsPic;
                                    }
                                }
                                else
                                {
                                    goodsPic = gsModel[0].Pic;
                                }
                            }
                        }
                        else
                        {
                            goodsPic = item.ProductImage;
                        }

                        #region 订单详情
                        Order_Decimal _Decimal = new Order_Decimal
                        {
                            Id = IdHelper.GetId(),
                            Deleted = false,
                            CreateTime = order_.CreateTime,
                            CreatorId = order_.CreatorId,
                            OrderMaster_Id = order_.Id,
                            OrderCode = order_.OrderCode,
                            Product_Id = item.GoodId,
                            Products_Id = item.GoodItemId,
                            Products_Num = item.Num,
                            ProductImage = goodsPic,
                            ProductNames = item.ProductNames,
                            ProductitemNames = item.ProductitemNames,
                            ProductPrice = item.ProductPrice,
                            SumProducts = (item.Num * item.ProductPrice),
                            DATA0 = "0"
                        };
                        _Decimals.Add(_Decimal);
                        list.Add(res);

                        #endregion

                        #region 库存信息
                        Outbound_Details _Details = new Outbound_Details
                        {
                            Id = IdHelper.GetId(),
                            Deleted = false,
                            CreateTime = order_.CreateTime,
                            CreatorId = order_.CreatorId,
                            Product_Id = item.GoodId,
                            Products_Id = item.GoodItemId,
                            productName = item.ProductNames,
                            productsName = item.ProductitemNames,
                            Outbound_Num = item.Num,
                            OrderMater_Id = order_.Id,
                            OrderCode = order_.OrderCode,
                            Price = item.ProductPrice,
                            oldBalance = q.Num,
                            newBalance = (q.Num - item.Num),
                            Bound_Flag = 1,
                            DATA0 = q.Flag.ToString(),
                            TotalPrice = (item.Num * item.ProductPrice)

                        };
                        outbound_s.Add(_Details);

                        #endregion
                        //删除购物车
                        if (res != null)
                        {
                            await Db.DeleteAsync(res);
                        }

                    }
                    
                }
                else
                {
                    ProductDto product = new ProductDto
                    {
                        Id = item.GoodId,
                        itemId = item.GoodItemId
                    };
                    _product.Add(product);
                    if (product != null)
                    {
                        return _product;
                    }
                    throw new Exception("库存不足");
                }
            }

            if (_Decimals.Count() != 0)
            {
                try
                {
                    int t = await Db.InsertAsync(_Decimals, false);

                    int bound = await Db.InsertAsync(outbound_s, false);//添加减少库存信息

                }
                catch (Exception e)
                {
                    throw new Exception("订单生成失败");
                }
            }

            return _product;
        }


        /// <summary>
        /// 直接生成订单
        /// </summary>
        /// <param name="_dto"></param>
        /// <param name="order_"></param>
        /// <returns></returns>
        private async Task<List<ProductDto>> STOrderAsync(SetOrderDto _dto, Order_Master order_)
        {
            Log.Information("进入订单立即购买方式 ======》 ");
            List<ProductDto> _product = new List<ProductDto>();
            List<Order_Decimal> _Decimals = new List<Order_Decimal>();
            List<Outbound_Details> outbound_s = new List<Outbound_Details>();
            //存储购物车中有的数据 res
            //List<Shop_Cart> list = new List<Shop_Cart>();

            decimal totalPrice = 0;
            int totalNum = 0;
            foreach (var item in _dto.GoodItems)
            {
                Log.Information("订单加入商品规格Id = {0}",item.GoodItemId);
                var gsModel = Db.GetEntity<BTB_GoodsSpecificationsItem>(item.GoodItemId);
                Log.Information("订单加入商品规格的商品Id = {0}", gsModel.GoodsID);
                var gModel = Db.GetEntity<BTB_Goods>(gsModel.GoodsID);
                string str = $"EXEC WashNum '{gsModel.GoodsID}','{gsModel.GoodsSpecificationsItemID}'";
                var q = DbHelperSQL.QueryForObject<NumCode>(str);
                Log.Information("订单加入商品规格的库存 = {0} 和 购买数量 ={1}", q.Num, item.GoodNum);
                //对比库存数量和购买数量
                if (q.Num > item.GoodNum)
                {
                    totalPrice += item.GoodNum * gsModel.Price;
                    totalNum += item.GoodNum;
                    #region 订单详情
                    Order_Decimal _Decimal = new Order_Decimal
                    {
                        Id = IdHelper.GetId(),
                        Deleted = false,
                        CreateTime = order_.CreateTime,
                        CreatorId = order_.CreatorId,
                        OrderMaster_Id = order_.Id,
                        OrderCode = order_.OrderCode,
                        Product_Id = gsModel.GoodsID,
                        Products_Id = item.GoodItemId,
                        Products_Num = item.GoodNum,
                        ProductImage = gsModel.Pic.IsNullOrEmpty() ? gsModel.Pic : gModel.GoodsPic,
                        ProductNames = gModel.GoodsName,
                        ProductitemNames = gsModel.GoodsSpecifications,
                        ProductPrice = gsModel.Price,
                        SumProducts = (item.GoodNum * gsModel.Price),
                        DATA0="0",
                    };
                    _Decimals.Add(_Decimal);

                    #endregion

                    #region 库存信息
                    Outbound_Details _Details = new Outbound_Details
                    {
                        Id = IdHelper.GetId(),
                        Deleted = false,
                        CreateTime = order_.CreateTime,
                        CreatorId = order_.CreatorId,
                        Product_Id = gsModel.GoodsID,
                        Products_Id = item.GoodItemId,
                        productName=gModel.GoodsName,
                        productsName=gsModel.GoodsSpecifications,
                        Outbound_Num= item.GoodNum,
                        OrderMater_Id=order_.Id,
                        OrderCode=order_.OrderCode,
                        Price=gsModel.Price,
                        oldBalance= q.Num,
                        newBalance=(q.Num-item.GoodNum),
                        Bound_Flag =1,
                        DATA0= q.Flag.ToString(),
                        TotalPrice = (item.GoodNum * gsModel.Price)
                         
                    };
                    outbound_s.Add(_Details);

                    #endregion

                }
                else
                {
                    throw new Exception("订单生成失败," + gModel.GoodsName + gsModel.GoodsSpecifications+"库存不足");
                    
                    //ProductDto product = new ProductDto
                    //{
                    //    Id = gsModel.GoodsID,
                    //    itemId = item.GoodItemId
                    //};
                    //_product.Add(product);
                    //if (product != null)
                    //{
                    //    return _product;
                    //}
                   
                }
            }


            if (_Decimals.Count() != 0)
            {
                try
                {
                    order_.TotalPrice = totalPrice;
                    order_.Totalnum = totalNum;

                    int t = await Db.InsertAsync(_Decimals, false);

                    int bound = await Db.InsertAsync(outbound_s, false);//添加减少库存信息
                  
                }
                catch (Exception e)
                {
                    throw new Exception("订单生成失败");
                }
            }
            else
            {
                throw new Exception("订单生成失败,无商品！");
            }

            return _product;
        }

        /// <summary>
        /// 购物车生成订单
        /// </summary>
        /// <param name="_dto"></param>
        /// <param name="order_"></param>
        /// <returns></returns>
        private async Task<List<ProductDto>> STCartOrderAsync(SetOrderDto _dto, Order_Master order_)
        {
            List<ProductDto> _product = new List<ProductDto>();
            List<Order_Decimal> _Decimals = new List<Order_Decimal>();
            List<Shop_Cart> _ShopCars = new List<Shop_Cart>();
            List<Outbound_Details> outbound_s = new List<Outbound_Details>();
            var cartList = Db.GetIQueryable<Shop_Cart>().Where(p => p.CreatorId.Equals(_Operator.UserId) && _dto.CartIds.Contains(p.Id)).ToList();
            decimal totalPrice = 0;
            int totalNum = 0;
            foreach (var item in cartList)
            {

                var gsModel = Db.GetEntity<BTB_GoodsSpecificationsItem>(item.Products_Id);
                var gModel = Db.GetEntity<BTB_Goods>(gsModel.GoodsID);
                string str = $"EXEC WashNum '{gsModel.GoodsID}','{item.Products_Id}'";
                var q = DbHelperSQL.QueryForObject<NumCode>(str);
                if (q.Num > item.ShopNum)
                {
                    totalPrice += (decimal)item.ShopNum * gsModel.Price;
                    totalNum += (int)item.ShopNum;
                    Order_Decimal _Decimal = new Order_Decimal
                    {
                        Id = IdHelper.GetId(),
                        Deleted = false,
                        CreateTime = order_.CreateTime,
                        CreatorId = order_.CreatorId,
                        OrderMaster_Id = order_.Id,
                        OrderCode = order_.OrderCode,
                        Product_Id = gsModel.GoodsID,
                        Products_Id = gsModel.GoodsSpecificationsItemID,
                        Products_Num = item.ShopNum,
                        ProductImage = gsModel.Pic,
                        ProductNames = gModel.GoodsName,
                        ProductitemNames = gsModel.GoodsSpecifications,
                        ProductPrice = gsModel.Price,
                        SumProducts = (item.ShopNum * gsModel.Price),
                    };
                    _Decimals.Add(_Decimal);

                    //int t = await Db.InsertAsync(_Decimal);

                    item.Deleted = true;
                    _ShopCars.Add(item);
                    //await Db.UpdateAsync(item);
                }
                else
                {
                    throw new Exception("订单生成失败," + gModel.GoodsName + gsModel.GoodsSpecifications + "库存不足");

                    //ProductDto product = new ProductDto
                    //{
                    //    Id = gsModel.GoodsID,
                    //    itemId = gsModel.GoodsSpecificationsItemID
                    //};
                    //_product.Add(product);
                }
            }

            if (_Decimals.Count() != 0)
            {
                try
                {
                    order_.TotalPrice = totalPrice;
                    order_.Totalnum = totalNum;

                    int t = await Db.InsertAsync(_Decimals, false); //加入订单
                    int m = await Db.UpdateAsync(_ShopCars, false); //删除购物车
                    int bound = await Db.InsertAsync(outbound_s, false); //添加减少库存信息

                }
                catch (Exception e)
                {
                    throw new Exception("订单生成失败");
                }
            }
            else
            {
                throw new Exception("订单生成失败,无商品！");
            }

            return _product;
        }

        /// <summary>
        /// 购物车生成订单
        /// </summary>
        /// <param name="_dto"></param>
        /// <param name="order_"></param>
        /// <returns></returns>
        private async Task<List<ProductDto>> AddCartOrderAsync(OrderDto _dto, Order_Master order_)
        {
            List<ProductDto> _product = new List<ProductDto>();

            foreach (var item in _dto._products)
            {
                string str = $"EXEC WashNum '{item.GoodId}','{item.GoodItemId}'";
                var q = DbHelperSQL.QueryForObject<NumCode>(str);
                if (q.Num < item.Num)
                {
                    var res = Db.GetIQueryable<Shop_Cart>().FirstOrDefault(p => p.CreatorId.Equals(_Operator.UserId) && p.Products_Id.Equals(item.GoodItemId));
                    Order_Decimal _Decimal = new Order_Decimal
                    {
                        Id = IdHelper.GetId(),
                        Deleted = false,
                        CreateTime = order_.CreateTime,
                        CreatorId = order_.CreatorId,
                        OrderMaster_Id = order_.Id,
                        OrderCode = order_.OrderCode,
                        Product_Id = item.GoodId,
                        Products_Id = item.GoodItemId,
                        Products_Num = item.Num,
                        ProductImage = item.ProductImage,
                        ProductNames = item.ProductNames,
                        ProductitemNames = item.ProductitemNames,
                        ProductPrice = item.ProductPrice,
                    };
                    //   _Decimals.Add(_Decimal);
                    int t = await Db.InsertAsync(_Decimal);
                    if (t > 0)
                    {
                        res.Deleted = true;
                        await Db.UpdateAsync(res);
                    }
                }
                else
                {
                    ProductDto product = new ProductDto
                    {
                        Id = item.GoodId,
                        itemId = item.GoodItemId
                    };
                    _product.Add(product);
                }
            }
            return _product;
        }

        /// <summary>
        /// 获取订单号
        /// </summary>
        /// <returns></returns>
        private static NumCode GetCode()
        {
            string sql = "execute Ordesq";

            var res = DbHelperSQL.QueryForObject<NumCode>(sql);

            return res;
        }

        public Task<List<GoodsDtom>> GetProduct()
        {
            throw new NotImplementedException();
        }

        public async Task<Order_Dto> GetOrderTheDataTwo(string Id)
        {
            var res = from p in Db.GetIQueryable<Order_Master>().Where(p => p.Id.Equals(Id))
                      join k in Db.GetIQueryable<BTB_StaffUser>() on p.CreatorId equals k.id
                      select new Order_Dto
                      {
                          Id = p.Id,
                          NameUser = k.NickName,
                          PhoneUser = k.phone,
                          YSMoney = p.YSMoney,
                          AllPrice = p.TotalPrice,
                          OrderState = p.OrderState,
                          CreatTime = p.CreateTime,
                          payeinfoName = p.payeinfoName,
                          payeinfoPhone = p.payeinfoPhone,
                          InvoiceData = p.InvoiceData,
                          InvoiceState = p.InvoiceState,
                          LscCompany = p.LscCompany,
                          LscNum = p.LscNumber,
                          PayState = p.PayState,
                          Note = p.DATA2,
                          payeinfoAddress = p.payeinfoAddress,
                          NumCode = p.OrderCode,
                          _UTicketDTO = Db.GetIQueryable<BS_UserVailTicket>(false).SingleOrDefault(r => r.Id.Equals(p.VailTicketId)),
                          Invoice = Db.GetIQueryable<Invoice_Info>(false).SingleOrDefault(r => r.Id.Equals(p.Invoice_InfoId)),
                          _Decimal = Db.GetIQueryable<Order_Decimal>(false).Where(s => s.OrderMaster_Id.Equals(p.Id))
                      };
            return await res?.FirstOrDefaultAsync();
        }
        public Order_Dto GetOrderTheDataTree(InputDTO input)
        {
            var res = from p in Db.GetIQueryable<Order_Master>().Where(p => p.Id.Equals(input.id))
                      join k in Db.GetIQueryable<BTB_StaffUser>() on p.CreatorId equals k.id
                      select new Order_Dto
                      {
                          Id = p.Id,
                          NameUser = k.NickName,
                          PhoneUser = k.phone,
                          AllPrice = p.TotalPrice,
                          OrderState = p.OrderState,
                          CreatTime = p.CreateTime,
                          payeinfoName = p.payeinfoName,
                          payeinfoPhone = p.payeinfoPhone,
                          PayState = p.PayState,
                          payeinfoAddress = p.payeinfoAddress,
                          NumCode = p.OrderCode,
                          Invoice = Db.GetIQueryable<Invoice_Info>(false).SingleOrDefault(r => r.Id.Equals(p.Invoice_InfoId)),
                          _Decimal = Db.GetIQueryable<Order_Decimal>(false).Where(s => s.OrderMaster_Id.Equals(p.Id))
                      };
            return  res?.FirstOrDefault();
        }

        /// <summary>
        /// 更新数据（订单状态）
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task UpdateDataTwoAsync(Order_Master data)
        {
            var res = await Db.UpdateSqlAsync<Order_Master>(s => s.Id == data.Id, ("OrderState", UpdateType.Equal, data.OrderState));
        }

        /// <summary>
        /// 订单发货，填写物流信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SendOrderAsync(ToSendOrderDTO input){
            var data = await GetEntityAsync(input.Id);
            data.LscCompany = input.Conmpany;
            data.LscNumber = input.Number;
            data.OrderState = 2;
            await UpdateAsync(data);
        }

        public void CancelOrder(string Id)
        {
            /// <summary>
            /// 取消订单
            /// </summary>
            /// <param name="canncl"></param>
            /// <returns></returns>

            try
            {
                if (Id.Length > 5)
                {
                    string key = RedisHelper.Get("Order:" + Id);
                    if (key!=null)
                    {
                        RedisHelper.Del("Order:" + Id);
                    }
                   
                }

                var res = Db.GetIQueryable<Order_Master>().SingleOrDefault(p => p.Id.Equals(Id));

                var rest = Db.GetIQueryable<Outbound_Details>().FirstOrDefault(r => r.OrderMater_Id.Equals(Id));
                var Products_Id = rest?.Products_Id;
                var Product_Id = rest?.Product_Id;

                var result = Db.GetIQueryable<BTB_GoodsSpecificationsItem>()
                    .FirstOrDefault(s => s.GoodsSpecificationsItemID.Equals(Products_Id) && s.GoodsID.Equals(Product_Id));
                if (res != null)
                {
                    if (res.OrderState == 0)
                    {
                        res.OrderState = 5;
                        res.PayState = 0;
                        Db.Update(res);

                        //返还代金券，修改状态为可使用
                        if (!res.VailTicketId.IsNullOrEmpty())
                        {
                            var vailTickets = Db.GetIQueryable<BS_UserVailTicket>().Where(x => x.Id.Equals(res.VailTicketId)).ToList();
                            if (vailTickets.Count > 0)
                            {
                                vailTickets[0].UseState = 0;
                                Db.Update(vailTickets[0]);
                            }
                        }

                        if (rest != null)
                        {
                            Db.Delete(rest);
                  
                        }

                        if (result != null)
                        {
                            result.Inventory = result.Inventory + decimal.ToInt32((decimal)rest.Outbound_Num);
                            Db.Update(result);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw;
            }
        }

        /// <summary>
        /// 统计
        /// </summary>
        /// <returns></returns>
        public async Task<List<Statistics>> GetStatistics()
        {

            var result = await Task.Run(() =>
            {
                var state = new[] { 0, 2, 3 };

                List<Statistics> _s = new List<Statistics>();
                foreach (var item in state)
                {
                    var str = string.Empty;
                    if (item == 3)
                    {
                        str = $"select count(Id) Count from Order_Decimal where DATA0 = {item} and CreatorId='{_Operator.UserId}'";

                    }
                    else
                    {
                        str = $"select count(Id) Count from Order_Master where OrderState = {item} and CreatorId='{_Operator.UserId}'";
                    }

                    var t = DbHelperSQL.QueryForObject<Statistics>(str);
                    Statistics statistics = new Statistics
                    {
                        State = item,
                        Count = t.Count
                    };
                    _s.Add(statistics);
                }
                return _s;

            });

            return result;
        }

        /// <summary>
        /// 首页统计 && a.CreateTime >= date1
        /// </summary>
        /// <returns></returns>
        public orderStatistics getStatistics()
        {
            
            DateTime date = DateTime.Now;
            DateTime date1 = date.AddDays(-7);
            var res = Db.GetIQueryable<Order_Master>();
            var res1= res.Where(p => p.OrderState == 1 && p.CreateTime >= date1 && p.CreateTime <= date);
            orderStatistics order = new orderStatistics
            {
               payCount=res.ToList().Count,
                allpayCount = res1.ToList().Count
            };

            return order;
        }

        /// <summary>
        /// 获取待评论
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<Order_Decimal>> GetDataOver(PageInput<Order_Decimal>  input)
        {
            var order_ = input.Search;
            var res = (from a in Db.GetIQueryable<Order_Decimal>()
                       join c in Db.GetIQueryable<Order_Master>().Where(x => x.OrderState > 2 && x.OrderState < 5) on a.OrderMaster_Id equals c.Id
                       join b in Db.GetIQueryable<BTB_Comment>() on a.Id equals b.Product_Id into ab
                       from b in ab.DefaultIfEmpty()
                       select new Order_Decimal{ 
                          Id = a.Id,
                          CreateTime = a.CreateTime,
                          CreatorId = a.CreatorId,
                          Deleted = a.Deleted,
                          OrderCode = a.OrderCode,
                          OrderMaster_Id = a.OrderMaster_Id,
                          ProductNames = a.ProductNames,
                          Product_Id = a.Product_Id,
                          Products_Id = a.Products_Id,
                          Products_Num = a.Products_Num,
                          ProductitemNames = a.ProductitemNames,
                          ProductPrice = a.ProductPrice,
                          ProductImage = a.ProductImage,
                          SumProducts = a.SumProducts,
                          UpdateTime = a.UpdateTime,
                          DATA0 = a.DATA0,
                          DATA1 = a.DATA1,
                          StarNum = b.Comment_State,
                          PLContent = b.Comment_Content
                      })
                      .Where(p=>p.CreatorId.Equals(_Operator.UserId));
            if (!order_.DATA0.IsNullOrEmpty())
            {
                res = res.Where(p=>p.DATA0.Equals(order_.DATA0));
            }
            var count = res.ToList().Count;
            var result=await res.OrderByDescending(p=>p.CreateTime).Skip((input.PageIndex - 1) * input.PageRows)
                .Take(input.PageRows)
                .ToListAsync();

            return new PageResult<Order_Decimal> { Data = result, Total = count };
            
        }

        /// <summary>
        /// 获取个人统计（未评论、已评论）数量
        /// </summary>
        /// <returns></returns>
        public async Task<object> GetOverSum() {

            var aCount = await (from a in Db.GetIQueryable<Order_Decimal>()
                          join c in Db.GetIQueryable<Order_Master>().Where(x => x.OrderState > 2 && x.OrderState < 5) on a.OrderMaster_Id equals c.Id
                          join b in Db.GetIQueryable<BTB_Comment>() on a.Id equals b.Product_Id into ab
                          from b in ab.DefaultIfEmpty()
                          select a).Where(p => p.CreatorId.Equals(_Operator.UserId)).ToListAsync();

            var count1 = aCount.Where(x => x.DATA0.Equals("0") || x.DATA0 == null).Count();
            var count2 = aCount.Where(x => !x.DATA0.Equals("0") && x.DATA0 != null).Count();

            var data = new { 
                Sum0 = count1,
                Sum1 = count2
            };


            return data;
        }

        /// <summary>
        /// 订单数据导出
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<string> GetOrderExploreFile(Order_DtoTwo input)
        {
            List<OrderExplorDTO> mdList = new List<OrderExplorDTO>();
            List<RSpanDTO> spanList = new List<RSpanDTO>();


            #region//组装数据
            //获取订单信息
            var mlist = await (from a in GetIQueryable()
                         join b in Db.GetIQueryable<BTB_StaffUser>() on a.CreatorId equals b.id into ab
                         from b in ab.DefaultIfEmpty()
                         join c in Db.GetIQueryable<BS_UserVailTicket>() on a.VailTicketId equals c.Id into ac
                         from c in ac.DefaultIfEmpty()
                         join d in Db.GetIQueryable<BTB_RefundMaster>() on a.Id equals d.OrderId into ad
                         from d in ad.DefaultIfEmpty()

                          select new
                         {
                             a.Id,
                             UNName = b.NickName,
                             URName = b.RealName,
                             USex = b.Sex,
                             UPhone = b.phone,
                             RName = a.payeinfoName,
                             RPhone = a.payeinfoPhone,
                             RAddress = a.payeinfoAddress,
                             a.OrderCode,
                             a.PayState,
                             a.OrderState,
                             ODNote = a.DATA2,
                             ODTPrice = a.YSMoney,
                             ODDcodePrice = c.Ticket_Amount,
                             ODYSPrice = a.TotalPrice,
                             a.LscNumber,
                             a.LscCompany,
                             RefundReason = d.Resion,
                             RefundState = d.State,
                             RefundNotReason = d.NoPassResion,
                             a.CreateTime,
                             a.InvoiceData,
                             a.InvoiceState
                          })
                          .WhereIf(input.state.HasValue, x => x.OrderState == input.state)
                          .WhereIf(input.startTime.HasValue, x=> x.CreateTime >= input.startTime)
                          .WhereIf(input.endTime.HasValue, x => x.CreateTime < input.endTime)
                          .ToListAsync();

            int rowIndex = 0;
            foreach (var item in mlist)
            {
                //组装数据
                OrderExplorDTO model = new OrderExplorDTO();
                model.UserNickName = item.UNName == null ? "" : item.UNName;
                model.UserRealName = item.URName == null ? "" : item.URName;
                model.Sex = item.USex.HasValue ? ( item.USex == 2 ? "女" : (item.USex == 1 ? "男" : "保密")) : "";
                model.Phone = item.UPhone == null ? "" : item.UPhone;
                model.ReciverName = item.RName == null ? "" : item.RName;

                model.ReciverPhone = item.RPhone == null ? "" : item.RPhone;
                if (!item.RAddress.IsNullOrEmpty())
                {
                    var ads = JsonConvert.DeserializeObject<AdressDTO>(item.RAddress);
                    model.ReciverAddress = ads.Address + ads.DetailedAddress;
                }
                else
                {
                    model.ReciverAddress = "";
                }
                model.OrderCode = item.OrderCode;
                model.PayType = item.PayState == 0 ? "未支付":(item.PayState == 1 ? "支付宝支付" : (item.PayState == 2 ? "小程序支付" :  "公众号H5支付"));
                model.OrderState =  Enum.GetName(typeof(OrderStateS), item.OrderState == null ? 0 : item.OrderState);
               
                model.OrderNote = item.ODNote == null ? "" : item.ODNote;
                model.YSPrice = ((decimal)item.ODYSPrice).ToString("0.00");
                model.DeductPrice = item.ODDcodePrice.ToString("0.00");
                model.PayPrice = item.ODTPrice.ToString("0.00");
                model.CreateTime = item.CreateTime.HasValue ? ((DateTime)item.CreateTime).ToString("yyyy-MM-dd HH:mm:ss") : "";

                //物流信息
                model.OddNum = item.LscNumber == null ? "" : item.LscNumber;
                model.OddCompany = item.LscCompany == null ? "" : item.LscCompany;

                //退款信息
                model.RefundReason = item.RefundReason == null ? "" : item.RefundReason;
                model.RefundState = item.RefundReason == null ? "" : (item.RefundState == 0 ? "退款中" : (item.RefundState == 1 ? "已退款" : "拒绝退款"));
                model.NotRefundReason = item.RefundNotReason == null ? "" : item.RefundNotReason;

                //发票信息
                if (!item.InvoiceData.IsNullOrEmpty())
                {
                    var ivs = JsonConvert.DeserializeObject<Invoice_Info>(item.InvoiceData);
                    model.InvoiceType = ivs.Invoice_Type == 0 ? "普通发票" : "增值税发票";
                    model.InvoiceTitle = ivs.Rise_Type == 1 ? "企业" : "个人";
                    model.Taker = ivs.PerName == null ? "" : ivs.PerName;
                    model.TakerPhone = ivs.Phone == null ? "" : ivs.Phone;
                    model.UnitName = ivs.UnitName == null ? "" : ivs.UnitName;
                    model.UnitTax = ivs.UnitTax == null ? "" : ivs.UnitTax;
                    model.UnitAddress = ivs.Unit_Address == null ? "" : ivs.Unit_Address;
                    model.UnitAccount = ivs.Accont == null ? "" : ivs.Accont;
                }

                model.InvoiceState = item.InvoiceState == 1 ? "待开发票" : (item.InvoiceState == 2 ? "已开发票" : "不需开票");



                //获取商品详情
                var gsList = (from a in Db.GetIQueryable<Order_Decimal>().Where(x => x.OrderMaster_Id.Equals(item.Id))
                              select new 
                              {
                                  GoodsName = a.ProductNames,
                                  GoodsItemName = a.ProductitemNames,
                                  GoodsPrice = a.ProductPrice.ToString("0.00"),
                                  GoodsNum = a.Products_Num.ToString(),
                                  GoodsTotalPrice = a.SumProducts.HasValue ? ((decimal)a.SumProducts).ToString("0.00") : (a.ProductPrice * (decimal)a.Products_Num).ToString("0.00")
                              }).ToList();

                if (gsList.Count > 1)
                {
                    RSpanDTO spModel = new RSpanDTO();
                    spModel.StartRow = rowIndex;
                    spModel.SpanRow = gsList.Count > 1 ? gsList.Count - 1 : 0;
                    spanList.Add(spModel);
                }

                rowIndex += gsList.Count == 0 ? 1 : gsList.Count;

                if (gsList.Count == 0)
                {
                    mdList.Add(model);
                }
                else
                {
                    foreach (var goods in gsList)
                    {
                        var sModel = model.DeepClone();
                        sModel.GoodsName = goods.GoodsName;
                        sModel.GoodsItemName = goods.GoodsItemName;
                        sModel.GoodsPrice = goods.GoodsPrice;
                        sModel.GoodsNum = goods.GoodsNum;
                        sModel.GoodsTotalPrice = goods.GoodsTotalPrice;
                        mdList.Add(sModel);
                    }
                }
            }
            #endregion

            if (!input.OrderCore.IsNullOrEmpty())
            {
                mdList = mdList.Where(x => x.UserNickName.Contains(input.OrderCore) || x.UserRealName.Contains(input.OrderCore) || x.GoodsName.Contains(input.OrderCore) || x.OrderCode.Contains(input.OrderCore)).ToList();
            }
           

            string[] titleArry = { "用户昵称", "用户姓名", "用户性别", "用户电话", "收货人姓名", "收货人电话", "收货人地址", "订单号", "支付方式", "订单状态", "快递方式", "订单备注", "订单总价", "优惠金额", "实际金额", "物流单号", "物流公司", "退款原因", "退款状态", "拒绝退款原因", "发票类型", "发票抬头", "收票人", "收票电话", "单位名称", "单位税号", "单位电话", "单位地址", "银行账号", "开票状态", "下单时间" , "商品名称", "商品规格" , "商品单价", "商品数量", "商品总价" };
            var dt = DataTableExtend.ToDataTable(mdList);

            DataTableToExcel dte = new DataTableToExcel();

           var path =  dte.OrderdatatableToExcel(dt, spanList, "商城订单信息表", titleArry, "商城订单信息表", "VisitSummary", _hostingEnvironment.WebRootPath);


            return path;
        }


        /// <summary>
        /// 订单号
        /// </summary>
        private class NumCode
        {  /// <summary>
           /// 订单号
           /// </summary>
            public string OrderNm { get; set; }

            /// <summary>
            /// 数量
            /// </summary>
            public int Num { get; set; }

            /// <summary>
            /// 数量
            /// </summary>
            public int Flag { get; set; }
        }

        //public async Task<PageResult<Order_Decimal>> GetOrders(PageInput<Order_Decimal> input)
        //{
        //    var q = (from aa in Order_Master)
        //}

        #endregion 私有成员
    }
}